<?php
/*
 * Created on 30/08/2008
 *
 * @author Matias Mirabelli <admin@moyrax.com>
 */
# @TableAnnotation( name="Usuarios", entity="class" )

class ClassLoader extends ClassFactory
{
	/******Singleton******/

	private static $instance = null;

	public static function getInstance()
	{
		if ( self::$instance == null ) {
			self::$instance = new ClassLoader();
		}

		return( self::$instance );
	}

	public function ClassLoader()
	{
		//$class = new ReflectionClass( "ClassName" );
	}
	/*********************/

	private $reflectorCache = array();
	private $environVar = array();


	public function getAnnotations( $object )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->getAnnotations() );
	}

	public function getDeclaredAnnotation( $object, $class )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->getDeclaredAnnotation( $class ) );
	}

    public function getConstructor( $object )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->getConstructor() );

	}

    public function getMethod( $object, $name )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->getMethod($name) );
	}

    public function getMethods( $object )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->getMethods() );

	}

    public function getProperty( $object, $name )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->getProperty($name) );
	}

    public function getProperties( $object )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->getProperties() );

	}

    public function getConstants( $object )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->getConstants() );

	}

    public function getConstant( $object, $name )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->getConstant($name) );
	}

    public function getInterfaces( $object )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->getInterfaces() );

	}

    public function isInterface( $object )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->isInterface() );

	}

    public function isAbstract( $object )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->isAbstract() );

	}

    public function isFinal( $object )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->isFinal() );

	}

    public function getModifiers( $object )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->getModifiers() );

	}

    public function isInstance( $object, $class )
	{
		$reflect = $this->getReflector( $object );

		return( $reflect->isInstance($class) );
	}

	/**
	 * Busca en cache o crea una nueva instancia
	 * de reflector para el objeto especificado.
	 *
	 * @param $object Objeto de referencia.
	 */
	private function getReflector( $object )
	{
		$class = get_class($object);

		foreach( $this->reflectorCache as $key => $value )
		{
			if ( $key == $class )
			{
				return( $value );
			}
		}

		$reflector = new ReflectionClassEx( $object );

		$this->reflectorCache[$class] = $reflector;

		return( $reflector );
	}

	public function setEnvironVar( $varName, $value )
	{
		$this->environVar[$varName] = $value;
	}

	public function expandEnvironVars( $paths = null )
	{
		// Reemplaza las variables por los directorios reales.
		//
		foreach( $paths as $key => $value )
		{
			$value = $this->expandEnvironValue( $value );

			$paths[$key] = $value;
		}

		return( $paths );
	}

	public function expandEnvironValue( $data )
	{
		foreach( $this->environVar as $key => $value )
		{

			$data = str_replace( '{' . $key . '}', $value, $data );
		}

		return( $data );
	}

	public function addContextPaths( $pathList )
	{
		$pathList = $this->expandEnvironVars( $pathList );

		// Agrega los directorios a los includes.
		//
		foreach( $pathList as $key => $value )
		{
			$this->addIncludePath( $value );
		}
	}
}
?>
